package com.delay.redis.queue.controller;

import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.Set;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @program: SpringBootDemos
 * @description:
 * @author: Kangsen
 * @create: 2022-07-11 14:07
 **/
@RestController
@Slf4j
@RequestMapping("/customer")
public class CustomerController {

    @Resource
    private JedisPool jedisPool;

    @PostConstruct
    public void customer(){
        Jedis jedis = jedisPool.getResource();
        /**
         * 同一个任务可能会被多个进程取到之后再使用 zrem 进行争抢，那些没抢到的进程都是白取了一次任务，这是浪费。
         * 解决办法：将 zrangebyscore 和 zrem 使用 lua 脚本进行原子化操作，这样多个进程之间争抢任务时就不会出现这种浪费了。
         *
         *
         * 这玩意的核心就是搞个线程不断去redis取 zset的超时数据  然后处理
         */
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(5,10,15L,TimeUnit.SECONDS,new LinkedBlockingQueue<>());
        threadPoolExecutor.submit((Runnable) () -> {
            log.info("超时订单检查线程");
            while (true){
                Set<String> taskIdSet = jedis.zrangeByScore("order", 0 , System.currentTimeMillis() - 30 * 1000, 0,10);
                if (taskIdSet == null || taskIdSet.isEmpty()) {
                    //log.info("没有订单任务");
                }else{
                    for (String s : taskIdSet) {
                        Long zrem = jedis.zrem("order", s);
                        log.info("从延时队列中获取到订单号：{}  当前时间:{}",zrem, LocalDateTime.now());
                    }
                }
                try {
                    TimeUnit.MILLISECONDS.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
    }
}
